﻿using System;

namespace FreshMeat.Storage
{
   /// <summary>
   /// Cross-platforms substitute for System.IO.Path (which is not available in
   /// a Portable Class Library).
   /// </summary>
   public static class Path
   {
      /// <summary>
      /// Character used to separate folder names in a path.
      /// </summary>
      public const char FolderSeparatorChar = '\\';

      /// <summary>
      /// Character used to indicate the start of an extension.
      /// </summary>
      public const char ExtensionChar = '.';

      /// <summary>
      /// Renames a file or folder.
      /// </summary>
      /// <param name="path">Path to the file or folder.</param>
      /// <param name="newName">New name.</param>
      /// <returns>Path with new name.</returns>
      public static string Rename(string path, string newName)
      {
         if (path == null)
            throw new ArgumentNullException("path");
         if (newName == null)
            throw new ArgumentNullException("newName");

         var location = GetLocation(path);

         var tempFilePath = Append(location, newName);
         return tempFilePath;
      }

      /// <summary>
      /// Gets the location of a file or folder.
      /// In other words, return everything before the file name or last folder name.
      /// </summary>
      /// <param name="path">Path to a file or folder.</param>
      /// <returns>Path to where the file or folder is located.</returns>
      public static string GetLocation(string path)
      {
         if (path == null)
            throw new ArgumentNullException("path");

         var slashIndex = path.LastIndexOf(FolderSeparatorChar);

         var location = slashIndex > 0 ? path.Substring(0, slashIndex) : "";
         return location;
      }

      /// <summary>
      /// Gets the name of the file or folder.
      /// </summary>
      /// <param name="path">Path to a file or folder.</param>
      /// <returns>The name of the file or folder.</returns>
      public static string GetName(string path)
      {
         if (path == null)
            throw new ArgumentNullException("path");
         if (path.Length == 0)
            throw new ArgumentException("Cannot be empty.", "path");

         var lastSlash = path.LastIndexOf(FolderSeparatorChar);
         if (lastSlash + 1 == path.Length)
            throw new ArgumentException(string.Format("Cannot end with a '{0}'.", FolderSeparatorChar), "path");

         var name = path.Substring(lastSlash + 1);
         return name;
      }

      /// <summary>
      /// Gets the name without the last extension.
      /// </summary>
      /// <param name="path">Path to a file or folder.</param>
      /// <returns>The name of the file or folder without the last extension.</returns>
      public static string GetNameWithoutLastExtension(string path)
      {
         var name = GetName(path);

         var dotIndex = name.LastIndexOf(ExtensionChar); // last dot

         var result = dotIndex > 0 ? name.Substring(0, dotIndex) : name;
         return result;
      }

      /// <summary>
      /// Gets the name without any extensions.
      /// </summary>
      /// <param name="path">Path to a file or folder.</param>
      /// <returns>The name of the file or folder without any extension(s).</returns>
      public static string GetNameWithoutExtensions(string path)
      {
         var name = GetName(path);

         var dotIndex = name.IndexOf(ExtensionChar); // first dot

         var result = dotIndex > 0 ? name.Substring(0, dotIndex) : name;
         return result;
      }

      /// <summary>
      /// Appends a file name, folder name or relative path to another path.
      /// </summary>
      /// <param name="path1">Path to a folder; can be an empty string.</param>
      /// <param name="path2">Path to add; if empty then path is returned unchanged.</param>
      /// <returns></returns>
      public static string Append(string path1, string path2)
      {
         if (path1 == null)
            throw new ArgumentNullException("path1");
         if (path2 == null)
            throw new ArgumentNullException("path2");

         if (path2.Length == 0)
            return path1;

         if (path2[0] == FolderSeparatorChar)
            throw new ArgumentException(string.Format("Cannot start with '{0}'.", FolderSeparatorChar), "path2");

         if (path1.Length == 0)
            return path2;

         if (path1[path1.Length - 1] == FolderSeparatorChar)
            return path1 + path2;

         return path1 + FolderSeparatorChar + path2;
      }
   }
}
